﻿#include "atmosphere.h"
#include <cstdio>
#include <iostream>

ImageBlock::ImageBlock(int count, int width_, int high_)
{
	led_count = count;
	pixel_len = (width_ + high_) * 2;
	width = width_;
	high = high_;
	pixel_interval = pixel_len / led_count;
	printf("pixel_interval:%d(%d, %d)\r\n", pixel_interval, pixel_len, led_count);
	block = new rect_t[width / pixel_interval * 2 + high / pixel_interval * 2];
	rgb = new color_t[width / pixel_interval * 2 + high / pixel_interval * 2];
	partitioning();
}

ImageBlock::~ImageBlock()
{
	delete []block;
	delete []rgb;
}

int ImageBlock::get_high(int move_x)
{
	int move = 0;
	if (move_x > width / 2)
		move_x = width - move_x;

	move = move_x * (high / 2) / (width / 2);

	if (move < 5)
		move = 5;
	else if (move > 100)
		move = 100;
	return move;
}

int ImageBlock::get_width(int move_y)
{
	int move = 0;
	if (move_y > high / 2)
		move_y = high - move_y;

	move = move_y * (width / 2) / (high / 2);

	if (move < 1)
		move = 1;
	else if (move > 100)
		move = 100;
	return move;
}

void ImageBlock::partitioning(void)
{
	int move_x = 0;
	int move_y = 0;
	int high_proportion = 0;
	int cnt = 0;

	// 上
	move_x = 0;
	printf("%d, %d, %d, %d\r\n", move_x, pixel_interval, move_x + pixel_interval, width);
	while ((move_x + pixel_interval) < width)
	{
		high_proportion = get_high(move_x);
		block[cnt].x = move_x;
		block[cnt].y = 0;
		block[cnt].w = pixel_interval;
		block[cnt].h = high_proportion;
		move_x += pixel_interval;
		printf("(%d, %d, %d, %d)\r\n", block[cnt].x, block[cnt].y, block[cnt].w, block[cnt].h);
		cnt++;
	}

	// 右
	move_y = 0;
	while ((move_y + pixel_interval) < high)
	{
		high_proportion = get_width(move_y);
		block[cnt].x = width - high_proportion;
		block[cnt].y = move_y;
		block[cnt].w = high_proportion;
		block[cnt].h = pixel_interval;
		move_y += pixel_interval;
		cnt++;
	}

	// 下
	move_x = width;
	while ((move_x - pixel_interval) > pixel_interval)
	{
		high_proportion = get_high(move_x);
		block[cnt].x = move_x - pixel_interval;
		block[cnt].y = high - high_proportion;
		block[cnt].w = pixel_interval;
		block[cnt].h = high_proportion;
		move_x -= pixel_interval;
		cnt++;
	}

	// 左
	move_y = high;
	while ((move_y - pixel_interval) > pixel_interval)
	{
		high_proportion = get_high(move_y);
		block[cnt].x = move_y - pixel_interval;
		block[cnt].y = 0;
		block[cnt].w = high_proportion;
		block[cnt].h = pixel_interval;
		move_y -= pixel_interval;
		cnt++;
	}
	block_cnt = cnt;
	std::cout << cnt << std::endl << width / pixel_interval * 2 + high / pixel_interval * 2 << std::endl;
}

typedef struct
{
	color_t rgb;
	int cnt;
}color_cnt_t;

static void rgb_cnt_handle(color_cnt_t *rgb_cnt, color_t *rgb, int count)
{
	int pos = 0;
	bool flag = true;
	int i = 0;
	for (i = 0; i < count; i++)
	{
		if (rgb->r == rgb_cnt[i].rgb.r &&
			rgb->g == rgb_cnt[i].rgb.g &&
			rgb->b == rgb_cnt[i].rgb.b)
		{
			rgb_cnt[i].cnt++;
			return;
		}
		if (!rgb_cnt[i].cnt && flag)
		{
			pos = i;
			flag = false;
		}
	}
	if (i >= count)
	{
		rgb_cnt[pos].rgb.r = rgb->r;
		rgb_cnt[pos].rgb.g = rgb->g;
		rgb_cnt[pos].rgb.b = rgb->b;
	}
}

static void rgb_cnt_max_color(color_cnt_t* rgb_cnt, color_t* rgb, int count)
{
	int pos = 0;
	int cnt = 0;
	for (int i = 0; i < count; i++)
	{
		if (rgb_cnt[i].cnt > rgb_cnt[pos].cnt)
		{
			pos = i;
		}
	}
	rgb->r = rgb_cnt[pos].rgb.r;
	rgb->g = rgb_cnt[pos].rgb.g;
	rgb->b = rgb_cnt[pos].rgb.b;
}

void ImageBlock::get_block_cnt_max_color(rect_t *pos, color_t *rgb)
{
	color_cnt_t *rgb_cnt = new color_cnt_t[pos->w * pos->h];
	color_t rgb_tmp;

	memset(rgb_cnt, 0, pos->w * pos->h * sizeof(color_cnt_t));
	for (int y = pos->y; y < pos->y + pos->h; y++)
	{
		for (int x = pos->x; x < pos->x + pos->w; x++)
		{
			rgb_tmp = bitmap.get_rgb(x, y);
			rgb_cnt_handle(rgb_cnt, &rgb_tmp, pos->w * pos->h);
		}
	}
	rgb_cnt_max_color(rgb_cnt, rgb, pos->w * pos->h);
	delete []rgb_cnt;
}

int ImageBlock::get_rgb(color_t **rgb_tmp)
{
	bitmap.refresh();
	for (int i = 0; i < block_cnt; i++)
	{
		get_block_cnt_max_color(block + i, rgb + i);
	}
	*rgb_tmp = rgb;
	return block_cnt;
}